﻿using Furion.FriendlyException;
using HiSportApplet.Application.Common.WeChatOpen.Dtos;
using HiSportApplet.Application.Service.Auth.Dtos;
using HiSportApplet.Application.Service.Auth.Dtos.EncryptKeyDtos;
using Newtonsoft.Json;
using System.Text;


namespace HiSportApplet.Application.Common.WeChatOpen
{
    /// <summary>
    /// 微信授权服务
    /// </summary>
    public class WeChatOpenService
    {
        /// <summary>
        /// 获取用户唯一标识OpenId和会员密钥SessionKey
        /// </summary>
        /// <param name="code"></param>
        /// <param name="appId"></param>
        /// <param name="appSecret"></param>
        /// <returns></returns>
        public OpenIdAndSessionKey GetOpenIdAndSessionKey(string code, string appId, string appSecret)
        {
            string text = "?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
            string requestUri = "https://api.weixin.qq.com/sns/jscode2session" + text;
            using HttpClient httpClient = new HttpClient();
            byte[] result = httpClient.GetByteArrayAsync(requestUri).Result;
            return JsonConvert.DeserializeObject<OpenIdAndSessionKey>(Encoding.UTF8.GetString(result));
        }
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <param name="session_key"></param>
        /// <returns></returns>
        public WeixinAppUserInfo GetUser(string encryptedData, string iv, string session_key)
        {
            return JsonConvert.DeserializeObject<WeixinAppUserInfo>(Cryptography.AES_decrypt(encryptedData, session_key, iv));
        }

        public WeixinAppPhoneNumber GetPhoneNumber(string encryptedData, string iv, string session_key)
        {
            return JsonConvert.DeserializeObject<WeixinAppPhoneNumber>(Cryptography.AES_decrypt(encryptedData, session_key, iv));
        }

        public async Task<WeixinResult> CreateQRCode(string url, string data, string access_token)
        {
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage result = client.PostAsync(string.Format(url, access_token), new StringContent(data)).Result;
                if (result.Content.Headers.ContentType.MediaType == "image/jpeg")
                {
                    WeixinResult weixinResult = new WeixinResult
                    {
                        IsSuccess = true
                    };
                    WeixinResult weixinResult2 = weixinResult;
                    weixinResult2.Msg = Convert.ToBase64String(await result.Content.ReadAsByteArrayAsync());
                    return weixinResult;
                }

                if (result.Content.Headers.ContentType.MediaType == "application/json")
                {
                    dynamic val = DynamicJson.Parse(result.Content.ReadAsStringAsync().Result);
                    WeixinResult weixinResult3 = new WeixinResult();
                    weixinResult3.IsSuccess = false;
                    weixinResult3.Msg = val.errmsg;
                    return weixinResult3;
                }
            }

            return new WeixinResult
            {
                IsSuccess = false,
                Msg = "未处理的二维码类型，请联系客服。"
            };
        }

        public async Task<WeixinResult> CreateWXaQRCode(string data, string access_token)
        {
            string url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token={0}";
            return await CreateQRCode(url, data, access_token);
        }

        public async Task<WeixinResult> GetWXaCode(string data, string access_token)
        {
            string url = "https://api.weixin.qq.com/wxa/getwxacode?access_token={0}";
            return await CreateQRCode(url, data, access_token);
        }

        public async Task<WeixinResult> GetWXaCodeUnLimit(string data, string access_token)
        {
            string url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}";
            return await CreateQRCode(url, data, access_token);
        }


        /// <summary>
        /// 获取接口调用凭证
        /// </summary>
        /// <param name="appId">APPID</param>
        /// <param name="secret">秘钥</param>
        /// <returns></returns>
        public static async Task<string> GetToken(string appId, string secret)
        {
                                  

            var domain = WeChatOpenSettings.Domain;
            string requestUri = $@"{domain}/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}";

            using HttpClient httpClient = new HttpClient();
            byte[] response = await httpClient.GetByteArrayAsync(requestUri);
            var result = Encoding.UTF8.GetString(response);
            var data = JsonConvert.DeserializeObject<GrtTokenDto>(result);
            if (data == null) throw Oops.Oh("获取token异常,未得到任何数据");
            if (data.errcode != 0) throw Oops.Oh($"获取token异常,errcode:{data.errcode},errmsg:{data.errmsg}");
            if (string.IsNullOrWhiteSpace(data.access_token)) throw Oops.Oh($"获取token异常,未获取到TOKEN");
            return data.access_token;

        }


        /// <summary>
        /// 获取用户EncryptKey
        /// </summary>
        /// <returns></returns>
        public static async Task<List<KeyInforList>> EncryptKey(EncryptKeyRequest input)
        {
            /*该接口用于获取用户encryptKey。 会获取用户最近3次的key，每个key的存活时间为3600s。*/

            var token = input.Token;

            var domain = WeChatOpenSettings.Domain;
            var  url = $"{domain}/wxa/business/getuserencryptkey?access_token={token}&openid={input.OpenId}&signature={input.signature}&sig_method={input.sig_method}";
            var result = await HttpClientHelper.HttpPostAsync(url);


            var data = JsonConvert.DeserializeObject<EncryptKeyResponse>(result);
            if (data == null) throw Oops.Oh("获取token异常,未得到任何数据");
            if (data.errcode != 0) throw Oops.Oh($"获取token异常,errcode:{data.errcode},errmsg:{data.errmsg}");
           return  data.key_info_list;     

        }

        /// <summary>
        /// 获取用户的电话号码
        /// </summary>
        /// <param name="token"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        public async Task<string> GetPhoneNumber2(string token, string postData)
        {
            var domain = WeChatOpenSettings.Domain;
            string url = $@"{domain}/wxa/business/getuserphonenumbe?access_token={token} ";
            var result = await HttpClientHelper.HttpPostAsync(url, postData);
            return result;
          
        }
    }
    public class HttpClientHelper
    {
        /// <summary>
        /// 发起POST同步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
        /// <param name="headers">填充消息头</param>        
        /// <returns></returns>
        public static string HttpPost(string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
        {
            postData = postData ?? "";
            using (HttpClient client = new HttpClient())
            {
                client.Timeout = TimeSpan.FromMinutes(1);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
                {
                    if (contentType != null)
                        httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);

                    HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
                    return response.Content.ReadAsStringAsync().Result;
                }
            }
        }


        /// <summary>
        /// 发起POST异步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
        /// <param name="headers">填充消息头</param>        
        /// <returns></returns>
        public static async Task<string> HttpPostAsync(string url, string postData = null, string contentType = "application/json", int timeOut = 30, Dictionary<string, string> headers = null)
        {
            postData = postData ?? "";
            using (HttpClient client = new HttpClient())
            {
                client.Timeout = new TimeSpan(0, 0, timeOut);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
                {
                    if (contentType != null)
                        httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);

                    HttpResponseMessage response = await client.PostAsync(url, httpContent);
                    return await response.Content.ReadAsStringAsync();
                }
            }
        }

        /// <summary>
        /// 发起GET同步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string HttpGet(string url, string contentType = "application/json", Dictionary<string, string> headers = null)
        {
            using (HttpClient client = new HttpClient())
            {
                if (contentType != null)
                    client.DefaultRequestHeaders.Add("ContentType", contentType);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                HttpResponseMessage response = client.GetAsync(url).Result;
                return response.Content.ReadAsStringAsync().Result;
            }
        }

        /// <summary>
        /// 发起GET异步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static async Task<string> HttpGetAsync(string url, string contentType = "application/json", Dictionary<string, string> headers = null)
        {
            using (HttpClient client = new HttpClient())
            {
                if (contentType != null)
                    client.DefaultRequestHeaders.Add("ContentType", contentType);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                HttpResponseMessage response = await client.GetAsync(url);
                return await response.Content.ReadAsStringAsync();
            }
        }
    }
}
